/*
 * Copyright (C), 2014-2016, org.esaydev
 * FileName: HttpUtil.java
 * Author:   jian
 * Date:     2016年3月14日 下午7:36:15
 */
package org.easydev.wechat.common.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;

/**
 * <Description> http工具类<br>
 * 
 * @author jian<br>
 */
public class HttpUtil {

    /**
     * LOGGER
     */
    private final static Logger LOGGER = LoggerFactory.getLogger(HttpUtil.class);

    /**
     * Description: 结果输出，输出文字信息，一般用于异步请求或错误结果输出<br>
     * 
     * @param outMsg 需要输出的结果
     * @param response <br>
     */
    public static void write(String outMsg, HttpServletResponse response) {
        try {
            if (StringUtils.isBlank(outMsg)) {
                response.getWriter().print(outMsg);
            }
        } catch (IOException e) {
            LOGGER.error("[wechat write response error:] ", e);
        }
    }

    /**
     * Description: 结果输出，以json形式输出结果<br>
     * 
     * @param outMsg 需要输出的结果
     * @param response <br>
     */
    public static void write(Object object, HttpServletResponse response) {
        try {
            if (null != object) {
                response.getWriter().print(JSONObject.toJSON(object));
            }
        } catch (IOException e) {
            LOGGER.error("[wechat write response error:] ", e);
        }
    }

    /**
     * 发送https请求
     * 
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式（GET、POST）
     * @param outputStr 提交的数据
     * @return 返回微信服务器响应的信息
     */
    public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        BufferedReader bufferedReader = null;
        InputStreamReader inputStreamReader = null;
        InputStream inputStream = null;
        HttpsURLConnection conn = null;
        try {
            TrustManager[] tm = {
                new SimpleX509TrustManager()
            };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            URL url = new URL(requestUrl);
            conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod(requestMethod);
            conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            inputStream = conn.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }

            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            conn.disconnect();

            return buffer.toString();
        } catch (ConnectException ce) {
            LOGGER.error("连接超时:", ce);
        } catch (Exception e) {
            LOGGER.error("https请求异常：", e);
        } finally {
            // 释放资源
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    LOGGER.error("IOException", e);
                }
            }
            if (null != inputStreamReader) {
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    LOGGER.error("IOException", e);
                }
            }
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    LOGGER.error("IOException", e);
                }
            }
            if (null != conn) {
                conn.disconnect();
            }
        }
        return null;
    }

    public static String urlEncodeUTF8(String source) {
        String result = source;
        try {
            result = java.net.URLEncoder.encode(source, "utf-8");
        } catch (UnsupportedEncodingException e) {
            LOGGER.error("urlEncodeUTF8 异常：{}", e);
        }
        return result;
    }

    /**
     * Description: 微信POST请求<br>
     * 
     * @param url <br>
     * @param <br>
     * @return <br>
     */
    public static String sendPost(String url, String param) {
        StringBuffer sb = new StringBuffer();
        URL postUrl = null;
        OutputStreamWriter out = null;
        BufferedReader reader = null;
        HttpURLConnection connection = null;
        try {
            postUrl = new URL(url);
            connection = (HttpURLConnection) postUrl.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
            connection.setRequestProperty("content-type", "application/x-www-form-urlencoded");
            connection.setRequestProperty("Accept-Charset", "UTF-8");
            connection.setRequestMethod("POST");
            connection.setUseCaches(false);
            out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
            out.write(param);
            out.flush();
            out.close();
            reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();
            connection.disconnect();
        } catch (MalformedURLException e) {
            LOGGER.error("MalformedURLException", e);
        } catch (IOException e) {
            LOGGER.error("IOException", e);
        } finally {
            if (out != null)
                try {
                    out.close();
                } catch (IOException e) {
                    LOGGER.error("IOException", e);
                }
            if (reader != null)
                try {
                    reader.close();
                } catch (IOException e) {
                    LOGGER.error("IOException", e);
                }
        }
        return sb.toString();
    }

    /**
     * Description: 微信get请求<br>
     * 
     * @param url <br>
     * @return <br>
     */
    public static String sendGet(String url) {
        LOGGER.info("[http get request] url:{}", url);
        URL postUrl = null;
        StringBuffer sb = new StringBuffer();
        OutputStreamWriter out = null;
        BufferedReader reader = null;
        HttpURLConnection connection = null;
        try {
            postUrl = new URL(url);
            connection = (HttpURLConnection) postUrl.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line;
            sb = new StringBuffer();
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();
            connection.disconnect();
        } catch (MalformedURLException e) {
            LOGGER.error("MalformedURLException", e);
        } catch (IOException e) {
            LOGGER.error("IOException", e);
        } finally {
            if (out != null)
                try {
                    out.close();
                } catch (IOException e) {
                    LOGGER.error("IOException", e);
                }
            if (reader != null)
                try {
                    reader.close();
                } catch (IOException e) {
                    LOGGER.error("IOException", e);
                }
        }
        LOGGER.info("[http get request] result:{}", sb.toString());
        return sb.toString();
    }

}
